package com.inspur.edp.udt.designtime.manager.generatecmpcode;


import com.inspur.edp.cef.designtime.api.operation.CommonDetermination;
import com.inspur.edp.cef.designtime.api.operation.CommonOperation;
import com.inspur.edp.cef.designtime.api.operation.CommonValidation;
import com.inspur.edp.lcm.fs.api.IFsService;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.GspProject;
import com.inspur.edp.lcm.metadata.api.entity.MetadataProject;
import com.inspur.edp.lcm.metadata.api.service.FileService;
import com.inspur.edp.lcm.metadata.api.service.MetadataProjectService;
import com.inspur.edp.lcm.metadata.api.service.MetadataService;
import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.SimpleDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.validation.ValidationInfo;
import com.inspur.edp.udt.designtime.api.utils.UdtUtils;
import com.inspur.edp.udt.designtime.manager.generatecmpcode.javacodegenerator.JavaBaseCommonCompCodeGenerator;
import com.inspur.edp.udt.designtime.manager.generatecmpcode.javacodegenerator.JavaBaseCompCodeGenerator;
import com.inspur.edp.udt.designtime.manager.generatecomponent.ComponentGenUtil;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.io.IOException;
import java.nio.file.Paths;
import javax.management.relation.RoleUnresolved;

public class JavaCodeFileGenerator {

  private String relativePath;
  private UnifiedDataTypeDef udtDef;
  private String compAssemblyName;
  private IFsService iFsService;
  private FileService fileService;
  private static final String codeFileExtension = ".java";

  public JavaCodeFileGenerator(GspMetadata metadata) {
    this.relativePath = metadata.getRelativePath();
    GspProject metadataProj = SpringBeanUtils.getBean(MetadataService.class)
        .getGspProjectInfo(relativePath);
    this.udtDef = (UnifiedDataTypeDef) metadata.getContent();
    this.compAssemblyName = metadataProj.getProjectNameSpace();
    this.fileService = SpringBeanUtils.getBean(FileService.class);
    this.iFsService = SpringBeanUtils.getBean(IFsService.class);
  }

  public final void JavaGenerate() {
    javaGenerateSingleValidations();
    javaGenerateCommonValidations();
    javaGenerateCommonDeterminations();
  }

  private static final String determinationDirName = "UDTDeterminations";

  private void javaGenerateCommonDeterminations() {
    String path = javaPrepareDir(determinationDirName);
    if (udtDef instanceof ComplexDataTypeDef) {

      for (CommonDetermination determination : udtDef.getDtmAfterCreate()) {
        if (determination.getIsRef() || (!determination.getIsGenerateComponent() && !UdtUtils
            .checkNull(determination.getComponentId()))) {
          continue;
        }
        javaDtmCodeGenerate(determination, path);
      }

      for (CommonDetermination determination : udtDef.getDtmAfterModify()) {
        if (determination.getIsRef() || (!determination.getIsGenerateComponent()) && !UdtUtils
            .checkNull(determination.getComponentId())) {
          continue;
        }
        javaDtmCodeGenerate(determination, path);
      }

      for (CommonDetermination determination : udtDef.getDtmBeforeSave()) {
        if (determination.getIsRef() || (!determination.getIsGenerateComponent() && !UdtUtils
            .checkNull(determination.getComponentId()))) {
          continue;
        }
        javaDtmCodeGenerate(determination, path);
      }
    }
  }

  private static final String validationDirName = "UDTValidations";

  private void javaGenerateCommonValidations() {
    String path = javaPrepareDir(validationDirName);
    if (udtDef instanceof ComplexDataTypeDef) {
      java.util.ArrayList<String> ids = new java.util.ArrayList<String>();

      for (CommonValidation validation : udtDef.getValBeforeSave()) {
        if (validation.getIsRef() || (!validation.getIsGenerateComponent() && !UdtUtils
            .checkNull(validation.getComponentId()))) {
          continue;
        }
        javaVldCodeGenerate(validation, path);
        ids.add(validation.getID());
      }

      for (CommonValidation validation : udtDef.getValAfterModify()) {
        if (validation.getIsRef() || (!validation.getIsGenerateComponent() && !UdtUtils
            .checkNull(validation.getComponentId()))) {
          continue;
        }
        if (!ids.contains(validation.getID())) {
          javaVldCodeGenerate(validation, path);
        }
      }
    }
  }

  private void javaGenerateSingleValidations() {
    String path = javaPrepareDir(validationDirName);
    if (udtDef instanceof SimpleDataTypeDef) {

      for (ValidationInfo validation : udtDef.getValidations()) {
        if (!validation.getIsGenerateComponent() && !UdtUtils.checkNull(validation.getCmpId())) {
          continue;
        }
        javaSingleVldCodeGenerate(validation, path);
      }
    }
  }

  private String getMetaProjName(GspProject projInfo) {
    String boProjName = projInfo.getMetadataProjectName().toLowerCase();
    return boProjName.substring(0, 0) + boProjName.substring(0 + boProjName.indexOf('-') + 1);
  }


  private String javaPrepareDir(String actionDirName) {

    String generatingAssembly = ComponentGenUtil
        .prepareJavaPackageName(udtDef.getDotnetAssemblyName()).replace(".", UdtUtils.getSeparator());

    MetadataProjectService service = SpringBeanUtils.getBean(MetadataProjectService.class);

    String compModulePath = service.getJavaCompProjectPath(relativePath);

    String compositePath = String
        .format("%1$s%2$s%3$s", compModulePath, UdtUtils.getSeparator(), generatingAssembly.toLowerCase());
    String path = UdtUtils
        .getCombinePath(compositePath, udtDef.getCode().toLowerCase(), actionDirName.toLowerCase());
    if (!fileService.isDirectoryExist(path)) {
      fileService.createDirectory(path);
    }
    return path;
  }

  private void javaDtmCodeGenerate(CommonDetermination determination, String dirPath) {
    javaGenerateSingleFile(determination, dirPath);
  }

  private void javaVldCodeGenerate(CommonValidation validation, String dirPath) {
    javaGenerateSingleFile(validation, dirPath);
  }

  private void javaSingleVldCodeGenerate(ValidationInfo validationInfo, String dirPath) {
    javaGenerateSingleFile(validationInfo, dirPath);
  }

  private void javaGenerateSingleFile(CommonOperation operation, String dirPath) {
    JavaBaseCommonCompCodeGenerator codeGen = JavaCmpCodeGeneratorFactory
        .javaGetGenerator(udtDef, operation, compAssemblyName, relativePath);

    String originalFilePath = UdtUtils
        .getCombinePath(relativePath, ComponentGenUtil.ComponentDir, codeGen + codeFileExtension);

    String filePathExe = fileService
        .getCombinePath(dirPath, codeGen.getCompName() + codeFileExtension);
    //此两处判断用来兼容原来没有对应文件夹情形
    if (fileService.isFileExist(originalFilePath)) {
      return;
    }
    if ((fileService.isFileExist(filePathExe))) {
      return;
    }
    iFsService.createFile(filePathExe, codeGen.generate());
  }

  private void javaGenerateSingleFile(ValidationInfo vldInfo, String dirPath) {
    JavaBaseCompCodeGenerator codeGen = JavaCmpCodeGeneratorFactory
        .javaGetGenerator(udtDef, vldInfo, compAssemblyName, relativePath);

    String originalFilePath = UdtUtils.getCombinePath(relativePath, ComponentGenUtil.ComponentDir,
        codeGen.getCompName() + codeFileExtension);

    String filePathExe = fileService
        .getCombinePath(dirPath, codeGen.getCompName() + codeFileExtension);
    //此两处判断用来兼容原来没有对应文件夹情形
    if (fileService.isFileExist(originalFilePath)) {
      return;
    }
    if ((fileService.isFileExist(filePathExe))) {
      return;
    }
    iFsService.createFile(filePathExe, codeGen.generate());
  }
}